package ui;

import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.LinkedList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.GroupLayout.Alignment;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.border.BevelBorder;
import javax.swing.border.LineBorder;


import logic.*;

/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class Partida extends javax.swing.JFrame{
	private Intro principal;
	private JPanel background;
	private JLabel blackboard;
	private List<JLabel> piezas;
	private JButton BotonMenu;
	private JButton BotonReiniciar;
	private JButton BotonUndo;
	private JButton BotonAyuda;
	private JLabel Estado, JuegoTerminado, Turno, Jugador1, Jugador2, Ganador, Ayuda;
	private Juego game;
	private Jugador j1,j2;
	private int accion, posfrom;
	private JLabel info;
	
	private List<Memento> mementos;
	private Thread cpuvscpu;
	
	public Partida(Intro principal) {
		super();
		this.principal=principal;
		piezas=new LinkedList<JLabel>();
		for(int i=0;i<9;i++)
			piezas.add(new JLabel());
		this.game=new Juego();
		j1=game.getJugadorConTurno();
		j2=game.getJugadores().get((game.getTurno()+1)%2);
		this.accion=0;
		this.posfrom=-1;
		game.setDificultad(principal.getDificultad());
		System.out.println(game);
		this.mementos=new LinkedList<Memento>();
		mementos.add(new Memento(game.copy()));
		initGUI();
		if(principal.getModo()==2){
			cpuvscpu=new Thread(){
				@Override
				public void run(){
					int p=-1;
					boolean colocadaCualquiera=false;
					while(!game.juegoTerminado()){
						esperar(2);
						Accion accioncpu=game.getAccionJugador();
						System.out.println("Accion de la cpu: " + accioncpu);
						p=accioncpu.getIdestino()+accioncpu.getJdestino()*3;
						if(game.piezasColocadas()==6){
							posfrom=accioncpu.getIfuente()+accioncpu.getJfuente()*3;
							game.setPiezaIn(posfrom,0);
							if(posfrom>=0)
								piezas.get(posfrom).setText("");
							else
								System.out.println("Posicion fuente fuera de rango - " + posfrom);
							}
						if(p<0)
							for(int i=0;i<piezas.size() && !colocadaCualquiera;i++)
								if(game.getPiezaFrom(i)==0){
									p=i;
									colocadaCualquiera=true;
								}
						game.setPiezaIn(p,game.getJugadorConTurno().getPieza());
						if(p>=0)
							switch(game.getJugadorConTurno().getPieza()){
							case 1:
								piezas.get(p).setText("O");
								break;
							case -1:
								piezas.get(p).setText("X");
								break;
							default:
								piezas.get(p).setText("E");
								break;
							}
						else 
							System.out.println("Posicion destino fuera de rango - " + p);
						game.cambiaTurno();
						String textturno;
						if(game.getTurno()==0)
							textturno="X";
						else if (game.getTurno()==1)
							textturno="O";
						else
							textturno="E";			
						Turno.setText("Turno: " + textturno);
						System.out.println(game.toString());
						accion=0;
						posfrom=-1;
						colocadaCualquiera=false;
					}
					mostrarResultado();
				}
			};
			cpuvscpu.start();
		}
	}
	
	
	
	private void initGUI() {
		try {
			int pxi=100, pyi=50;
			
			this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			this.setMaximumSize(new java.awt.Dimension(900, 590));
			this.setMinimumSize(new java.awt.Dimension(900, 590));
			this.addWindowListener(new WindowAdapter() {
				public void windowClosing(WindowEvent evt) {
					thisWindowClosing(evt);
				}
			});
			{
				background = new JPanel();
				getContentPane().add(background, BorderLayout.CENTER);
				background.setLayout(null);
				background.setSize(900, 590);
				{
					info = new JLabel();
					background.add(info);
					info.setText("Jorge Merino Garcia");
					info.setBounds(270, 505, 120, 20);
					info.setBackground(new java.awt.Color(67,85,72));
					info.setFont(new java.awt.Font("Eraser",1,10));
					info.setForeground(new java.awt.Color(255,255,255));
					info.setOpaque(false);
					info.setBorder(BorderFactory.createEmptyBorder());
				}
				{
					Estado = new JLabel();
					background.add(Estado);
					Estado.setText("ESTADO");
					Estado.setBounds(660, 50, 200, 20);
					Estado.setBackground(new java.awt.Color(67,85,72));
					Estado.setFont(new java.awt.Font("Eraser",1,20));
					Estado.setForeground(new java.awt.Color(255,255,255));
					Estado.setOpaque(false);
					Estado.setBorder(BorderFactory.createEmptyBorder());
				}
				{
					Jugador1 = new JLabel();
					background.add(Jugador1);
					String textj1;
					if(game.getJugadores().get(game.getTurno()).getPieza()==-1)
						textj1="X";
					else if (game.getJugadores().get(game.getTurno()).getPieza()==1)
						textj1="O";
					else
						textj1="E";
					Jugador1.setText("Jugador 1: " + textj1);
					Jugador1.setBounds(680, 80, 200, 20);
					Jugador1.setBackground(new java.awt.Color(67,85,72));
					Jugador1.setFont(new java.awt.Font("Eraser",1,15));
					Jugador1.setForeground(new java.awt.Color(255,255,255));
					Jugador1.setOpaque(false);
					Jugador1.setBorder(BorderFactory.createEmptyBorder());
				}
				{
					Jugador2 = new JLabel();
					background.add(Jugador2);
					String textj2;
					if(game.getJugadores().get((game.getTurno()+1)%2).getPieza()==-1)
						textj2="X";
					else if (game.getJugadores().get((game.getTurno()+1)%2).getPieza()==1)
						textj2="O";
					else
						textj2="E";
					Jugador2.setText("Jugador 2: " + textj2);
					Jugador2.setBounds(680, 100, 200, 20);
					Jugador2.setBackground(new java.awt.Color(67,85,72));
					Jugador2.setFont(new java.awt.Font("Eraser",1,15));
					Jugador2.setForeground(new java.awt.Color(255,255,255));
					Jugador2.setOpaque(false);
					Jugador2.setBorder(BorderFactory.createEmptyBorder());
				}
				{
					Turno = new JLabel();
					background.add(Turno);
					String textturno;
					if(game.getTurno()==0)
						textturno="X";
					else if (game.getTurno()==1)
						textturno="O";
					else
						textturno="E";			
					Turno.setText("Turno: " + textturno);
					Turno.setBounds(680, 130, 200, 20);
					Turno.setBackground(new java.awt.Color(67,85,72));
					Turno.setFont(new java.awt.Font("Eraser",1,15));
					Turno.setForeground(new java.awt.Color(255,255,255));
					Turno.setOpaque(false);
					Turno.setBorder(BorderFactory.createEmptyBorder());
				}
				{
					JuegoTerminado = new JLabel();
					background.add(JuegoTerminado);
					JuegoTerminado.setText("Juego Terminado");
					JuegoTerminado.setBounds(660, 180, 200, 30);
					JuegoTerminado.setBackground(new java.awt.Color(67,85,72));
					JuegoTerminado.setFont(new java.awt.Font("Eraser",1,20));
					JuegoTerminado.setForeground(new java.awt.Color(255,150,50));
					JuegoTerminado.setOpaque(false);
					JuegoTerminado.setBorder(BorderFactory.createEmptyBorder());
					JuegoTerminado.setVisible(false);
				}
				{
					Ganador = new JLabel();
					background.add(Ganador);
					Ganador.setText("Ganador");
					Ganador.setBounds(680, 200, 200, 30);
					Ganador.setBackground(new java.awt.Color(67,85,72));
					Ganador.setFont(new java.awt.Font("Eraser",1,15));
					Ganador.setForeground(new java.awt.Color(255,255,255));
					Ganador.setOpaque(false);
					Ganador.setBorder(BorderFactory.createEmptyBorder());
					Ganador.setVisible(false);
				}
				{
					Ayuda = new JLabel();
					background.add(Ayuda);
					Ayuda.setText("");
					Ayuda.setBounds(750, 400, 120, 20);
					Ayuda.setBackground(new java.awt.Color(67,85,72));
					Ayuda.setFont(new java.awt.Font("Eraser",1,15));
					Ayuda.setForeground(new java.awt.Color(255,255,255));
					Ayuda.setOpaque(false);
					Ayuda.setBorder(BorderFactory.createEmptyBorder());
				}
				{
					BotonAyuda = new JButton();
					background.add(BotonAyuda);
					BotonAyuda.setText("AYUDA");
					BotonAyuda.setBounds(725, 350, 145, 40);
					BotonAyuda.setFont(new java.awt.Font("Eraser",1,20));
					BotonAyuda.setForeground(new java.awt.Color(255,255,255));
					BotonAyuda.setBackground(new java.awt.Color(67,85,72));
					BotonAyuda.setBorder(BorderFactory.createEtchedBorder(BevelBorder.LOWERED));
					BotonAyuda.setOpaque(false);
					BotonAyuda.addMouseListener(new MouseAdapter() {
						public void mouseClicked(MouseEvent evt) {
							BotonAyudaMouseClicked(evt);
						}
					});
				}
				{
					for (int i=0;i<9;i++){
						background.add(piezas.get(i));
						piezas.get(i).setFont(new java.awt.Font("Eraser",1,120));
						piezas.get(i).setForeground(new java.awt.Color(255,255,255));
						piezas.get(i).setOpaque(false);
						piezas.get(i).setBorder(BorderFactory.createEmptyBorder());
						piezas.get(i).setText("");
						
						piezas.get(i).setBounds(pxi, pyi, 88, 96);
						pxi+=180;
						if(i%3==2){
							pxi=100;
							pyi+=140;
						}
						piezas.get(i).addMouseListener(new MouseAdapter() {
							public void mouseClicked(MouseEvent evt) {
								piezasMouseClicked(evt);
							}
						});	
					}
					
				}
				{
					BotonUndo = new JButton();
					background.add(BotonUndo);
					BotonUndo.setText("DESHACER");
					BotonUndo.setFont(new java.awt.Font("Eraser",1,20));
					BotonUndo.setForeground(new java.awt.Color(255,255,255));
					BotonUndo.setBackground(new java.awt.Color(67,85,72));
					BotonUndo.setOpaque(false);
					BotonUndo.setBorder(BorderFactory.createEtchedBorder(BevelBorder.LOWERED));
					BotonUndo.setBounds(30, 495, 145, 40);
					BotonUndo.addMouseListener(new MouseAdapter() {
						public void mouseClicked(MouseEvent evt) {
							BotonUndoMouseClicked(evt);
						}
					});
				}
				{
					BotonReiniciar = new JButton();
					background.add(BotonReiniciar);
					BotonReiniciar.setText("REINICIAR");
					BotonReiniciar.setBounds(465, 495, 145, 40);
					BotonReiniciar.setFont(new java.awt.Font("Eraser",1,20));
					BotonReiniciar.setForeground(new java.awt.Color(255,255,255));
					BotonReiniciar.setBackground(new java.awt.Color(67,85,72));
					BotonReiniciar.setBorder(BorderFactory.createEtchedBorder(BevelBorder.LOWERED));
					BotonReiniciar.setOpaque(false);
					BotonReiniciar.addMouseListener(new MouseAdapter() {
						public void mouseClicked(MouseEvent evt) {
							BotonReiniciarMouseClicked(evt);
						}
					});
				}
				{
					BotonMenu = new JButton();
					background.add(BotonMenu);
					BotonMenu.setText("MENU");
					BotonMenu.setFont(new java.awt.Font("Eraser",1,20));
					BotonMenu.setForeground(new java.awt.Color(255,255,255));
					BotonMenu.setBackground(new java.awt.Color(67,85,72));
					BotonMenu.setOpaque(false);
					BotonMenu.setBorder(BorderFactory.createEtchedBorder(BevelBorder.LOWERED));
					BotonMenu.setBounds(725, 495, 145, 40);
					BotonMenu.addMouseListener(new MouseAdapter() {
						public void mouseClicked(MouseEvent evt) {
							BotonMenuMouseClicked(evt);
						}
					});
				}
				{
					blackboard = new JLabel();
					background.add(blackboard);
					blackboard.setBounds(0, -6, 900, 570);
					blackboard.setIcon(new ImageIcon(getClass().getClassLoader().getResource("ui/rayas2.png")));
				}
			}
			this.setSize(900, 590);
			pack();
			
		} catch (Exception e) {
		    //add your error handling code here
			e.printStackTrace();
		}
	}
	
	public Thread getCpuvscpu() {
		return cpuvscpu;
	}

	public void setCpuvscpu(Thread cpuvscpu) {
		this.cpuvscpu = cpuvscpu;
	}

	private void BotonMenuMouseClicked(MouseEvent evt) {
		System.out.println("BotonMenu.mouseClicked, event="+evt);
		Ayuda.setText("");
		this.principal.getBotonContinuar().setVisible(true);
		principal.setVisible(true);
		this.dispose();
	}
	
	private void BotonAyudaMouseClicked(MouseEvent evt) {
		int p=-1, pf=-1;
		System.out.println("BotonAyuda.mouseClicked, event="+evt);
		Accion accioncpu=game.getAccionJugador();
		System.out.println("Consejo al jugador: " + accioncpu);
		Ayuda.setText(accioncpu.toString2());
	}
	
	private void BotonUndoMouseClicked(MouseEvent evt) {
		System.out.println("BotonUndo.mouseClicked, event="+evt);
		Ayuda.setText("");
		if(mementos.size()>1)
			mementos.remove(mementos.size()-1).getGame();
		game=mementos.get(mementos.size()-1).getGame().copy();
		for(int i=0;i<piezas.size();i++){
			if(game.getPiezaFrom(i)==-1)
				piezas.get(i).setText("X");
			else if(game.getPiezaFrom(i)==1)
				piezas.get(i).setText("O");
			else if(game.getPiezaFrom(i)==0)
				piezas.get(i).setText("");
			else
				piezas.get(i).setText("E");
				
			piezas.get(i).setBorder(null);
		}
		JuegoTerminado.setVisible(false);
		Ganador.setVisible(false);
		
		String textturno;
		if(game.getTurno()==0)
			textturno="X";
		else if (game.getTurno()==1)
			textturno="O";
		else
			textturno="E";			
		Turno.setText("Turno: " + textturno);
		accion=0;
		posfrom=-1;
	}	
	
	private void BotonReiniciarMouseClicked(MouseEvent evt) {
		System.out.println("BotonReiniciar.mouseClicked, event="+evt);
		Ayuda.setText("");
		this.game=new Juego();
		j1=game.getJugadorConTurno();
		j2=game.getJugadores().get((game.getTurno()+1)%2);
		this.mementos=new LinkedList<Memento>();
		mementos.add(new Memento(game.copy()));
		for(int i=0;i<piezas.size();i++){
			piezas.get(i).setText("");
			piezas.get(i).setBorder(null);
		}
		JuegoTerminado.setVisible(false);
		Ganador.setVisible(false);
		
		String textturno;
		if(game.getTurno()==0)
			textturno="X";
		else if (game.getTurno()==1)
			textturno="O";
		else
			textturno="E";			
		Turno.setText("Turno: " + textturno);
		String textj1, textj2;
		if(game.getJugadores().get((game.getTurno()+1)%2).getPieza()==-1){
			textj1="O";
			textj2="X";
		}else if (game.getJugadores().get((game.getTurno()+1)%2).getPieza()==1){
			textj1="X";
			textj2="O";
		}else{
			textj1="E";
			textj2="E";
		}
		Jugador1.setText("Jugador 1: " + textj1);
		Jugador2.setText("Jugador 2: " + textj2);
	}
	
	private void piezasMouseClicked(MouseEvent evt) {
		int p=-1;
		boolean piezaColocadaPorJugador=false, colocadaCualquiera=false;
		for(int i=0;i<piezas.size();i++)
			if(piezas.get(i).equals(evt.getSource()))
				p=i;
		System.out.println("piezas[" + p + "].mouseClicked, event="+evt);

		if(principal.getModo()!=2){ /* Jugador vs..*/
			if(!game.juegoTerminado()){
				if(game.piezasColocadas()<6){
					if(game.getPiezaFrom(p)==0){
						game.setPiezaIn(p,game.getJugadorConTurno().getPieza());
						switch(game.getJugadorConTurno().getPieza()){
							case 1:
								piezas.get(p).setText("O");
								break;
							case -1:
								piezas.get(p).setText("X");
								break;
							default:
								piezas.get(p).setText("E");
								break;
						}
						
						game.cambiaTurno();
						String textturno;
						if(game.getTurno()==0)
							textturno="X";
						else if (game.getTurno()==1)
							textturno="O";
						else
							textturno="E";			
						Turno.setText("Turno: " + textturno);
						piezaColocadaPorJugador=true;
						System.out.println(game.toString());
					}else System.out.println("Intento de colocar pieza fallido en piezas[" + p + "]");
				}else if(game.piezasColocadas()==6){
					if(accion==0) /* quitar una pieza para colocarla en otro sitio */
						if(game.getPiezaFrom(p)==game.getJugadorConTurno().getPieza()){
							posfrom=p;
							piezas.get(posfrom).setBorder(LineBorder.createBlackLineBorder());
							accion=1;
						}else System.out.println("Intento de quitar pieza fallido en piezas[" + p + "]");
					else if(accion==1) /* colocamos una pieza que hemos quitado */ 
						if(game.getPiezaFrom(p)==0){
							game.setPiezaIn(posfrom,0);
							piezas.get(posfrom).setBorder(null);
							piezas.get(posfrom).setText("");
							game.setPiezaIn(p,game.getJugadorConTurno().getPieza());
							switch(game.getJugadorConTurno().getPieza()){
							case 1:
								piezas.get(p).setText("O");
								break;
							case -1:
								piezas.get(p).setText("X");
								break;
							default:
								piezas.get(p).setText("E");
								break;
							}
							
							game.cambiaTurno();
							String textturno;
							if(game.getTurno()==0)
								textturno="X";
							else if (game.getTurno()==1)
								textturno="O";
							else
								textturno="E";			
							Turno.setText("Turno: " + textturno);
							piezaColocadaPorJugador=true;
							System.out.println(game.toString());
							accion=0;
							posfrom=-1;
						}else if(game.getPiezaFrom(p)==game.getJugadorConTurno().getPieza()){
							piezas.get(posfrom).setBorder(null);	
							posfrom=p;
							piezas.get(posfrom).setBorder(LineBorder.createBlackLineBorder());	
						}
						else System.out.println("Intento de colocar pieza fallido en piezas[" + p + "]");	
				}
				
				if(!game.juegoTerminado()){
					if(piezaColocadaPorJugador && principal.getModo()==1){ /* Jugador vs CPU */
						Accion accioncpu=game.getAccionJugador();
						System.out.println("Accion de la cpu: " + accioncpu);
						p=accioncpu.getIdestino()+accioncpu.getJdestino()*3;
						if(game.piezasColocadas()==6){
							posfrom=accioncpu.getIfuente()+accioncpu.getJfuente()*3;
							game.setPiezaIn(posfrom,0);
							if(posfrom>=0)
								piezas.get(posfrom).setText("");
							else
								System.out.println("Posicion fuente fuera de rango - " + posfrom);
						}
						if(p<0)
							for(int i=0;i<piezas.size() && !colocadaCualquiera;i++)
								if(game.getPiezaFrom(i)==0){
									p=i;
									colocadaCualquiera=true;
								}
						game.setPiezaIn(p,game.getJugadorConTurno().getPieza());
						if(p>=0)
							switch(game.getJugadorConTurno().getPieza()){
							case 1:
								piezas.get(p).setText("O");
								break;
							case -1:
								piezas.get(p).setText("X");
								break;
							default:
								piezas.get(p).setText("E");
								break;
							}
						else
							System.out.println("Posicion destino fuera de rango - " + p);
						
						game.cambiaTurno();
						String textturno;
						if(game.getTurno()==0)
							textturno="X";
						else if (game.getTurno()==1)
							textturno="O";
						else
							textturno="E";			
						Turno.setText("Turno: " + textturno);
						System.out.println(game.toString());
						accion=0;
						posfrom=-1;
					}
					if(game.juegoTerminado()) /* Juego Terminado por CPU */
						mostrarResultado();
					
					/* Se guarda el estado para poder deshacer */
					if(piezaColocadaPorJugador){
						mementos.add(new Memento(game.copy()));
						Ayuda.setText("");
					}
				}else{ /* Juego Terminado por jugador*/
					mostrarResultado();
				}
			}else{ /* Juego terminado. No se puede mover ficha*/
				mostrarResultado();
			}
		}
	}
	
	public void esperar (int segundos) {
		try {
			Thread.sleep (segundos*1000);
		} catch (Exception e) {
			System.out.println("Espera fallida");// Mensaje en caso de que falle
		}
	}
	private void mostrarResultado(){
		JuegoTerminado.setVisible(true);
		System.out.print("PARTIDA TERMINADA. ");
		if(game.esGanador(j1)){
			System.out.println("Ganador: "+ j1.getId() + " - Pieza: " + j1.getPieza());
			Ganador.setText("Ganador: Jugador 1");
		}else if(game.esGanador(j2)){
			System.out.println("Ganador: "+ j2.getId() + " - Pieza: " + j2.getPieza());
			Ganador.setText("Ganador: Jugador 2");
		}else{
			System.out.println("Ganador: NO SE SABE");
			Ganador.setText("Ganador: NO SE SABE");
		}
			
		Ganador.setVisible(true);
	}
	
	private void thisWindowClosing(WindowEvent evt) {
		System.out.println("this.windowClosing, event="+evt);
		this.principal.getBotonContinuar().setVisible(true);
		this.principal.setVisible(true);
		this.dispose();
	}
}
